package router

import (
	"bufio"
	"fmt"
	"github.com/gin-gonic/gin"
	"net"
	"net/http"
)

type ResInHandler struct {
}

func NewResInHandler() *ResInHandler {
	return &ResInHandler{}
}

func (handler *ResInHandler) RegisterRoutes(r *gin.RouterGroup) {
	r.GET("/res_in", handler.ResIn)
}

func (handler *ResInHandler) ResIn(ctx *gin.Context) {
	port := ctx.Query("port")
	if !isWhitePort(port) {
		ctx.String(http.StatusBadRequest, "Invaild port")
		return
	}

	//可监听本机任意端口，存在资源注入漏洞
	listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%s", port))
	if err != nil {
		ctx.String(http.StatusBadRequest, "listen failed, err:", err)
		return
	}

	for {
		conn, err := listener.Accept() // 等待客户端连接
		if err != nil {
			fmt.Println("accept failed, err:", err)
			continue
		}
		go process(conn) // 启动一个goroutine处理连接
	}
}

func process(conn net.Conn) {
	defer conn.Close() // 关闭连接
	for {
		reader := bufio.NewReader(conn)
		var buf [128]byte
		n, err := reader.Read(buf[:]) // 读取数据
		if err != nil {
			fmt.Println("read from client failed, err:", err)
			break
		}
		recvStr := string(buf[:n])
		fmt.Println("收到client端发来的数据：", recvStr)
		conn.Write([]byte(recvStr)) // 发送数据
	}
}

func isWhitePort(port string) bool {
	whitePortList := []string{"80", "8083"}
	for _, whitePort := range whitePortList {
		if whitePort == port {
			return true
		}
	}
	return false
}
